<template>
  <div class="myDialog">
    <!-- 素材对话框 -->
    <el-dialog :visible.sync="dialogVisible" :title="titleText" top="5vh" v-el-drag-dialog
      :close-on-press-escape="false" :close-on-click-modal="false" @close="handleClose" class="custom-dialog">
      <el-divider content-position="left">基本信息</el-divider>
      <el-form class="rule-container" :model="dialogForm" label-width="100px" :rules="rules" ref="dialogForm">
        <div class="rule-content">
          <el-form-item label="名称:" prop="Name">
            <el-input v-model="dialogForm.Name" :disabled="Action === 1" />
          </el-form-item>
          <el-form-item label="分类:" prop="ClassID">
            <el-cascader :disabled="Action === 1" style="width: 100%;" v-model="dialogForm.ClassID" ref="cascaderAddr"
              :options="classList"
              :props="{ value: 'value', label: 'label', children: 'children', emitPath: false, checkStrictly: true, expandTrigger: 'hover' }"
              @visible-change="elCascaderOnlick" @expand-change="elCascaderOnlick" placeholder="请选择分类"
              class="full-width" :popper-class="this.color === 'night' ? 'nightClass' : ''" />
          </el-form-item>
          <el-form-item label="文件标识:"
            v-if="Action === 1 && type === 'local' && dialogForm.Files && dialogForm.Files.length > 0">
            <el-input :value="dialogForm.Files.map(f => f.FileName).join('\n')" type="textarea"
              :rows="dialogForm.Files.length" readonly />
          </el-form-item>
          <el-form-item label="文件原名称:"
            v-if="Action === 1 && type === 'local' && dialogForm.Files && dialogForm.Files.length > 0">
            <el-input :value="dialogForm.Files.map(f => f.FileRawName).join('\n')" type="textarea"
              :rows="dialogForm.Files.length" readonly />
          </el-form-item>
          <el-form-item v-if="type === 'net'" label="服务器:" prop="NetFileSerID">
            <el-select style="width: 100%;" v-model="dialogForm.NetFileSerID" :disabled="Action === 1"
              placeholder="请选择服务器" :popper-class="this.color === 'night' ? 'nightClass' : ''"
              @change="handleServerChange">
              <el-option v-for="item in fileServerList" :key="item.ID" :label="item.Name" :value="item.ID">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="type === 'net'" label="目录:" prop="NetDirPath">
            <el-input v-if="Action === 1" v-model="dialogForm.NetDirPath" disabled></el-input>
            <el-cascader style="width: 100%;" v-else
              :popper-class="this.color === 'night' ? 'nightClass hasridio' : 'hasridio'"
              v-model="dialogForm.NetDirPath" :options="fileInfoList" :append-to-body="false" @change="NetDirPathChange"
              ref="cascaderMenu"
              :props="{ checkStrictly: true, emitPath: true, lazy: true, multiple: false, lazyLoad: handleLazyLoadFilePath }"
              clearable></el-cascader>
          </el-form-item>
          <el-form-item v-if="type === 'net'" label="跟踪更新:" prop="IsTrackUpdate">
            <el-select style="width: 100%;" v-model="dialogForm.IsTrackUpdate" :disabled="Action === 1"
              :popper-class="this.color === 'night' ? 'nightClass' : ''">
              <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="type === 'net'" label="跟踪删除:" prop="IsTrackDel">
            <el-select style="width: 100%;" v-model="dialogForm.IsTrackDel" :disabled="Action === 1"
              :popper-class="this.color === 'night' ? 'nightClass' : ''">
              <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="描述:" prop="Descp" :readonly="Action === 1">
            <el-input v-model="dialogForm.Descp" type="textarea" rows="5" :disabled="Action === 1" />
          </el-form-item>
          <el-form-item prop="Files" v-if="type === 'local'">
            <el-upload :class="this.color === 'night' ? 'nightUpload' : ''" ref="upload" v-model="dialogForm.Files"
              :accept="'.doc,.docx,.pdf,.ppt,.pptx'" v-if="type === 'local' && Action !== 1" class="upload-demo"
              action="#" drag :on-change="handleFileChange" :auto-upload="false" :show-file-list="true" multiple>
              <i class="el-icon-upload"></i>
              <div class="el-upload__text" style="width: 100%;">
                将文件拖到此处，或<em>点击上传</em>。仅支持".doc,.docx,.pdf,.ppt,.pptx"
              </div>
            </el-upload>
          </el-form-item>
        </div>
      </el-form>
      <!-- 分割线与dialog-footer的间距 -->
      <el-divider class="lineToFooter"></el-divider>
      <template #footer>
        <span class="dialog-footer">
          <el-button v-if="Action !== 1" type="primary" @click="handleSubmit"> 确认 </el-button>
          <el-button type="info" @click="handleClose">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import elDragDialog from "@/directive/el-drag-dialog";
import { Material_URLS } from "../api/request";
import { SMB_URLS } from "../api/request";
import { noTokenRequest } from "@/api/material";
import { directRequest } from "@/api/firstPage";

export default {
  name: "MaterialDialog",
  directives: {
    elDragDialog
  },
  data() {
    return {
      color: "",
      dialogVisible: false,
      Files: [],
      options: [
        {
          label: "是",
          value: 1
        },
        {
          label: "否",
          value: 2
        }
      ],
      hostOptions: [],
      smbOptions: [],
      KnowledgeIP: "", //知识库的IP
      rules: {
        Name: [{ required: true, message: "请输入素材名称" }],
        ClassID: [{ required: true, message: "请选择分类" }],
        Files: [{ required: true, message: "请上传文件" }],
        // SMB目录验证（兼容Windows/Linux路径）
        NetDirPath: [
          { required: true, message: "SMB目录不能为空", trigger: "change" }
          // {
          //   validator: (rule, value, callback) => {
          //     const winRegex = /^[a-zA-Z]:\$?:[^\\/:*?"<>|\r\n]+\$*[^\\/:*?"<>|\r\n]*$/;
          //     const linuxRegex = /^\/[^/:*?"<>|\r\n]*(?:\/[^/:*?"<>|\r\n]*)*$/;

          //     if (value && !winRegex.test(value) && !linuxRegex.test(value)) {
          //       callback(new Error("路径格式示例：Windows: \\folder\\share | Linux: /mnt/share"));
          //     } else {
          //       callback();
          //     }
          //   },
          //   trigger: "blur"
          // }
        ],

        // IP地址验证（仅格式校验）
        NetFileSerID: [
          { required: true, message: "服务器不能为空", trigger: "change" }
          // {
          //   validator: (rule, value, callback) => {
          //     const ipRegex =
          //       /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
          //     if (value && !ipRegex.test(value)) {
          //       callback(new Error("请输入有效的IPv4地址（如192.168.1.1）"));
          //     } else {
          //       callback();
          //     }
          //   },
          //   trigger: "blur"
          // }
        ],

        // 用户名（仅保留必填验证，移除格式校验）
        SmbUser: [{ required: true, message: "用户名不能为空", trigger: "blur" }],

        // 密码（仅保留必填和中文检测）
        SmbPwd: [
          { required: true, message: "密码不能为空", trigger: "blur" },
          {
            validator: (rule, value, callback) => {
              if (value && /[\u4e00-\u9fa5]/.test(value)) {
                callback(new Error("密码不能包含中文"));
              } else {
                callback();
              }
            },
            trigger: "blur"
          }
        ],
        IsTrackUpdate: [{ required: true, message: "请选择是否跟踪更新" }],
        IsTrackDel: [{ required: true, message: "请选择是否更踪删除" }]
      },
      fileServerList: [],
      fileInfoList: []
    };
  },
  props: {
    show: {
      type: Boolean,
      default: false
    },
    type: {
      type: String,
      default: ""
    },
    dialogForm: {
      type: Object,
      default: () => ({})
    },
    classList: {
      type: Array,
      default: () => []
    },
    Action: {
      type: Number,
      default: 0
    }
  },
  mounted() {
    this.color = localStorage.getItem("isNightMode") || "night";
    this.getFileServer();
  },
  computed: {
    titleText() {
      if (this.Action === 1) {
        return this.type === "local" ? "预览本地素材" : "预览网络素材";
      } else {
        return this.type === "local" ? "新增本地素材" : "新增网络素材";
      }
    }
  },
  watch: {
    show(val) {
      this.dialogVisible = val;
      this.Files = []
    }
  },
  created() { },
  methods: {
    getData() {
      this.getHostOptions();
    },
    async getHostOptions() {
      const res = await noTokenRequest(SMB_URLS.getFileServer);
      this.hostOptions = res.Data.map((item) => ({
        label: item.Name,
        value: item.ID
      }));
    },
    handleClose() {
      if (this.type === "local" && this.Action !== 1) {
        this.$refs.upload.clearFiles();
      }
      this.$refs.dialogForm.resetFields(); // 重置表单及验证状态
      this.dialogVisible = false;
      this.$emit("closeDialog");
    },
    handleSubmit() {
      this.$refs.dialogForm.validate((valid) => {
        if (valid) {
          this.$emit("submitDialog", this.dialogForm);
        } else {
          return false;
        }
      });
    },
    // 处理文件选择变化
    async handleFileChange(file, fileList) {
      //上传文件获取UUID
      // 1. 创建FormData对象
      try {
        // 确保file是原生File对象
        if (!(file instanceof File)) {
          file = file.raw; // 处理element-ui上传组件的特殊结构
        }

        const formData = new FormData();
        formData.append("file", file, file.name); // 第三个参数确保文件名传递

        const response = await fetch(Material_URLS.uploadFile, {
          method: "POST",
          body: formData
          // 不要手动设置Content-Type！浏览器会自动添加boundary
        });

        if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);
        const result = await response.json();
        // 提取文件名和后缀（带点号）
        const fileName = file.name;
        const fileExt = fileName.includes(".") ? fileName.substring(fileName.lastIndexOf(".")) : "";
        // 将文件信息保存到 dialogForm
        this.Files.push({
          FileRawName: fileName,
          FileType: fileExt, // 现在包含点号
          FileName: result.Data.UUID
        })
        this.dialogForm = {
          ...this.dialogForm,
          Files: this.Files
        };
        if (result.Status.StatusCode !== 0) {
          throw new Error(result.Status.Msg2Client);
        }

        return result.Data; // 返回实际有效数据
      } catch (error) {
        this.$message.error(`上传失败: ${error.message}`);
      }
    },
    async getFileServer() {
      const res = await directRequest("/zyq/get_file_server", {});
      if (res.Status.StatusCode === 0) {
        this.fileServerList = res.Data;
      }
    },
    async getFileListByDir(server, dir) {
      if (!server) return [];
      const data = {
        Host: server.SmbConf.SmbHost,
        Port: server.SmbConf.SmbPort,
        User: server.SmbConf.SmbUser,
        Password: server.SmbConf.SmbPwd,
        Path: dir
      };
      const res = await directRequest("/zyq/list_smb_file_info", data);
      if (res.Status.StatusCode === 0) {
        const nodeList = [];
        res.Data.forEach((item) => {
          if (item.IsDir) {
            nodeList.push({
              label: item.Name,
              value: item.Name,
              leaf: !item.HasChildren
            });
          }
        });
        return nodeList;
      } else {
        return [];
      }
    },
    async handleServerChange(val) {
      const server = this.fileServerList.find((item) => item.ID === val);
      const nodes = await this.getFileListByDir(server, "/");
      this.fileInfoList = nodes;
    },
    // 点击单选框的时候，收起下拉框
    NetDirPathChange(row) {
      this.$refs.cascaderMenu.toggleDropDownVisible();
    },
    async handleLazyLoadFilePath(node, resolve) {
      // 验证节点和必要属性
      if (!node || !node.value || !this.dialogForm?.NetFileSerID) {
        return resolve([]);
      }
      // 如果是叶子节点，直接返回空数组
      if (node.data?.leaf) {
        return resolve([]);
      }
      try {
        // 查找服务器
        const server = this.fileServerList?.find(item => item.ID === this.dialogForm.NetFileSerID);
        if (!server) {
          return resolve([]);
        }
        // 规范化路径，确保不重复添加斜杠
        const path = node.value.startsWith('/') ? node.value : `/${node.path.join('/')}`;
        // 获取文件列表
        const nodes = await this.getFileListByDir(server, path);
        resolve(nodes || []); // 确保返回数组，防止 undefined
      } catch (error) {
        resolve([]); // 错误时返回空数组，避免树组件卡住
      }
    },
    elCascaderOnlick() {
      let that = this;
      setTimeout(function () {
        document.querySelectorAll(".el-cascader-node__label").forEach((el) => {
          el.onclick = function () {
            this.previousElementSibling.click();
            that.$refs.cascaderAddr.dropDownVisible = false;
          };
        });
      }, 100);
    }
  }
};
</script>

<style lang="scss" scoped>
::v-deep .el-upload-dragger {
  border: 1px solid #d9d9d9;
}


.nightUpload {

  ::v-deep .el-upload-dragger,
  ::v-deep .el-upload-list__item:hover {
    background: #3e4252;
    border: none;
  }

  ::v-deep .el-upload-list__item-name,
  ::v-deep .el-upload-list__item-name [class^="el-icon"] {
    color: #fff;
  }

  .el-upload__text {
    color: #fff;
  }
}
</style>

<style lang="scss">
.hasridio {
  .el-cascader-panel .el-radio {
    display: inline-block !important;
  }
}
</style>
